/**
  **************************************************************************
  * File   : at32_board.c
  * Version: V1.2.4
  * Date   : 2020-08-26
  * Brief  : 1. Set of firmware functions to manage Leds, push-button and COM ports.
  *          2. initialize Delay Function and USB
  **************************************************************************
  */

#include "at32_board.h"
#include "stdio.h"

extern volatile uint32_t systickcount;
/* Suport printf function, useMicroLib is unnecessary */
#ifdef __CC_ARM
  #pragma import(__use_no_semihosting)
  struct __FILE
  {
    int handle;
  };
  
  FILE __stdout;
  
  void _sys_exit(int x)
  {
    x = x;
  }
#endif

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
  
/*delay macros*/
#define STEP_DELAY_MS	500

 
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{  
 // if((AT32_PRINT_UART->CTRL1&(1<<13)) == 0) return 0;

  USART_SendData(AT32_PRINT_UART, ch);
  while ( USART_GetFlagStatus(AT32_PRINT_UART, USART_FLAG_TRAC) == RESET );    
  return ch;
}

/**
  * @brief  Board initialize interface 
  *         init LED and BUTTON
  * @param  None
  * @retval None
  */
void AT32_Board_Init()
{
  /*initialize Delay Function*/
  Delay_init();
  LCD_GPIO_Init();
}
uint32_t HAL_GetTick(){
  return systickcount;
}


void LCD_GPIO_Init()
{
  GPIO_InitType GPIO_InitStructure;
  /*Enable the LED Clock*/
  RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOF|RCC_AHBPERIPH_GPIOA|RCC_AHBPERIPH_GPIOB, ENABLE);

  /*Configure the LED pin as ouput push-pull*/
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pins = GPIO_Pins_8|GPIO_Pins_11|GPIO_Pins_12|GPIO_Pins_15;		
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
  GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
  GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;	
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pins = GPIO_Pins_6;	
  GPIO_Init(GPIOF, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pins = GPIO_Pins_All;	
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/**
  * @brief  initialize UART1   
  * @param  bound: UART BaudRate
  * @retval None
  */
void UART_Print_Init(uint32_t bound)
{
  GPIO_InitType GPIO_InitStructure;
  USART_InitType USART_InitStructure;

  /*Enable the UART Clock*/
  RCC_AHBPeriphClockCmd(AT32_PRINT_UARTTX_GPIO_RCC | AT32_PRINT_UARTRX_GPIO_RCC, ENABLE);	
  RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_USART2, ENABLE);

  /* Configure the UART1 TX pin */
  GPIO_StructInit(&GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pins = AT32_PRINT_UARTTX_PIN; 
  GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
  GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
  GPIO_Init(AT32_PRINT_UARTTX_GPIO, &GPIO_InitStructure);

  /* Configure the UART1 RX pin */
  GPIO_InitStructure.GPIO_Pins = AT32_PRINT_UARTRX_PIN;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
  GPIO_Init(AT32_PRINT_UARTRX_GPIO, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOA, GPIO_PinsSource2, GPIO_AF_1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinsSource3, GPIO_AF_1);

  /*Configure UART param*/
  USART_StructInit(&USART_InitStructure);
  USART_InitStructure.USART_BaudRate = bound;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	

  USART_Init(USART2, &USART_InitStructure); 
  USART_Cmd(USART2, ENABLE);  
  USART_INTConfig(AT32_PRINT_UART, USART_INT_RDNE, ENABLE);
}
void NVIC_Configuration(void)
{
  NVIC_InitType NVIC_InitStructure;

  /* Enable the TMR3 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  initialize Delay function   
  * @param  None
  * @retval None
  */		   
void Delay_init()
{
  /*Config Systick*/
  SysTick_Config(SystemCoreClock/1000);
 // SysTick_CLKSourceConfig(SystemCoreClock/1000);
  // fac_us=(float)SystemCoreClock/(8 * 1000000);
  // fac_ms=fac_us*1000;
   //NVIC_Configuration();
  // SysTick_IRQn
}

/**
  * @brief  Inserts a delay time.
  * @param  nus: specifies the delay time length, in microsecond.
  * @retval None
  */
void Delay_us(u32 nus)
{
  int i = 64;
  while(--i);
}
void HAL_Delay(u16 nms){
   uint32_t tickstart = 0;
    tickstart = HAL_GetTick();
    while ((HAL_GetTick() - tickstart) < nms)
    {
        ;
    }
} 								  
/**
  * @brief  Inserts a delay time.
  * @param  nms: specifies the delay time length, in milliseconds.
  * @retval None
  */
void Delay_ms(u16 nms)
{
  HAL_Delay(nms);
}

/**
  * @brief  Inserts a delay time.
  * @param  sec: specifies the delay time length, in seconds.
  * @retval None
  */
void Delay_sec(u16 sec)
{
  u16 i;
  for(i=0; i<sec; i++)
  {
    Delay_ms(500);
    Delay_ms(500);
  }
}
	





